﻿using UnityEngine;
using System.Collections.Generic;

public class MockServer : MonoBehaviour
{
    public float TimeStep = 1f / 60;
    private uint serverFrame;  //游戏服务器的起始帧号
    public static float latency = 0.01f;
    public uint serverSendRate = 10; //服务端每隔10帧发送一次
    [SerializeField]
    private BallMotor serverBallMotor; //在客户端看到的黄色的球，是客户端收到的服务端发送过来的球的位置插值形成的
    public static MockServer instance;
    private List<BallCommand> moveCommandList;
    private List<BallCommand> executedBallCommandList = new List<BallCommand>();
    public BallMotor[] posNetObject;
    private void Awake()
    {
        instance = this;
        Time.fixedDeltaTime = TimeStep;
        moveCommandList = new List<BallCommand>();
        serverFrame = serverSendRate;
    }

    private void Start()
    {
        MockClient.instance.SyncServerInitSucess(serverSendRate);
    }
    private void FixedUpdate()
    {
        if (moveCommandList.Count > 0)
        {
            var command = moveCommandList[0];
            moveCommandList.RemoveAt(0);
            serverBallMotor.Move(command.moveDir);
            foreach (var target in posNetObject)
            {
                command.StoreResult(target.transform.position, target.rigid.velocity);
            }
            executedBallCommandList.Add(command);
        }

        if (serverFrame % serverSendRate == 0) // 服务器同步频率要低于其更新频率
        {
            if (executedBallCommandList.Count > 0)
            {
                var lastCommand = executedBallCommandList[executedBallCommandList.Count - 1];
                MockClient.instance.SyncServerDataToClient(serverFrame, lastCommand.frame, lastCommand.positionList, lastCommand.velocityList);
                S2CSyncPos();
                executedBallCommandList.Clear();
            }
        }

        serverFrame += 1;
    }

    private void S2CSyncPos()
    {
        var posNetList = new List<Vector3>();
        foreach (var target in posNetObject)
        {
            posNetList.Add(target.transform.position);
        }
        MockClient.instance.S2CSyncPos(serverFrame, posNetList.ToArray());
    }

    public void SendCommandToServer(uint clientFrame, Vector3 moveDir)
    {
        WaitTimeTool.WaitTime(latency, ReceiveCommandFromClient, new BallCommand(clientFrame, moveDir));
    }

    private void ReceiveCommandFromClient(BallCommand command)
    {
        moveCommandList.Add(command);
    }
}
